#pragma once
#include "timeout_exception.hpp"
#include "thread_pool.hpp"
#include "timer_wheel.hpp"
#include "task_wrapper.hpp"
#include <functional>
#include <future>
#include <chrono>
#include <memory>
#include <unordered_map>
#include <mutex>
#include <atomic>

namespace timeout_manager {

/**
 * 超时管理器核心类
 */
class TimeoutManager {
public:
    using Duration = std::chrono::milliseconds;
    
    /**
     * 统计信息结构
     */
    struct Statistics {
        size_t totalTasks;        // 总任务数
        size_t completedTasks;    // 已完成任务数
        size_t timeoutTasks;      // 超时任务数
        size_t cancelledTasks;    // 被取消任务数
        size_t activeTasks;       // 当前活跃任务数
        size_t queuedTasks;       // 队列中等待的任务数
    };
    
    /**
     * 构造函数
     */
    explicit TimeoutManager(
        size_t threadPoolSize = std::thread::hardware_concurrency(),
        size_t timerWheelSize = 3600,
        Duration timerTick = std::chrono::milliseconds(100)
    );
    
    /**
     * 析构函数
     */
    ~TimeoutManager();
    
    /**
     * 执行带超时的函数，返回future获取结果
     * 模板函数定义在头文件中
     */
    template<typename F, typename... Args>
    auto executeWithTimeout(Duration timeout, F&& func, Args&&... args)
        -> std::future<decltype(func(args...))> {
        
        using ReturnType = decltype(func(args...));
        
        // 1. 生成唯一任务ID
        auto taskId = generateTaskId();
        
        std::cout << "提交带超时任务: ID=" << taskId 
                  << ", 超时=" << timeout.count() << "ms" << " (TimeoutManager::executeWithTimeout)" <<std::endl;
        
        // 2. 绑定函数和参数
        auto taskFunc = std::bind(std::forward<F>(func), std::forward<Args>(args)...);
        
        // 3. 创建任务包装器
        auto wrapper = std::make_shared<TaskWrapper<ReturnType>>(taskId, taskFunc);
        
        // 4. 获取future
        auto future = wrapper->getFuture();
        
        // 5. 添加到活跃任务映射（使用类型擦除）
        {
            std::lock_guard<std::mutex> lock(tasksMutex_);
            activeTasks_[taskId] = std::make_shared<TaskCanceller>([wrapper]() {
                wrapper->cancel();
            });
        }
        
        // 6. 提交任务到线程池
        threadPool_->submit([this, wrapper, taskId]() {
            wrapper->execute();
            
            // 任务完成后清理
            cleanupTask(taskId);
            completedTasks_.fetch_add(1);
        });
        
        // 7. 设置超时定时器
        timerWheel_->addTimer(taskId, timeout, [this, wrapper, taskId]() {
            std::cout << "任务超时触发: ID=" << taskId << " (TimeoutManager::executeWithTimeout)"<< std::endl;
            
            // 设置任务超时
            wrapper->timeout();
            
            // 清理任务
            cleanupTask(taskId);
            timeoutTasks_.fetch_add(1);
        });
        
        totalTasks_.fetch_add(1);
        return future;
    }
    
    /**
     * 执行带超时和完成回调的函数
     */
    template<typename F, typename Callback, typename... Args>
    TaskHandle executeWithTimeoutAsync(
        Duration timeout,
        F&& func,
        Callback&& onComplete,
        Args&&... args) {
        
        using ReturnType = decltype(func(args...));
        
        auto taskId = generateTaskId();
        
        std::cout << "提交异步带超时任务: ID=" << taskId 
                  << ", 超时=" << timeout.count() << "ms" << std::endl;
        
        auto taskFunc = std::bind(std::forward<F>(func), std::forward<Args>(args)...);
        auto wrapper = std::make_shared<TaskWrapper<ReturnType>>(taskId, taskFunc);
        
        // 添加到活跃任务映射
        {
            std::lock_guard<std::mutex> lock(tasksMutex_);
            activeTasks_[taskId] = std::make_shared<TaskCanceller>([wrapper]() {
                wrapper->cancel();
            });
        }
        
        // 提交任务到线程池
        threadPool_->submit([this, wrapper, taskId, onComplete = std::forward<Callback>(onComplete)]() {
            wrapper->execute();
            
            // 执行完成回调
            try {
                if constexpr (std::is_void_v<ReturnType>) {
                    wrapper->getFuture().get(); // 检查是否有异常
                    onComplete();
                } else {
                    auto result = wrapper->getFuture().get();
                    onComplete(result);
                }
            } catch (const std::exception& e) {
                std::cout << "任务执行异常，跳过回调: " << e.what() << std::endl;
                // 这里可以扩展为支持错误回调
            }
            
            cleanupTask(taskId);
            completedTasks_.fetch_add(1);
        });
        
        // 设置超时定时器
        timerWheel_->addTimer(taskId, timeout, [this, wrapper, taskId]() {
            std::cout << "异步任务超时触发: ID=" << taskId << std::endl;
            wrapper->timeout();
            cleanupTask(taskId);
            timeoutTasks_.fetch_add(1);
        });
        
        totalTasks_.fetch_add(1);
        return TaskHandle(taskId);
    }
    
    /**
     * 取消指定任务
     */
    bool cancelTask(const TaskHandle& handle);
    
    /**
     * 获取统计信息
     */
    Statistics getStatistics() const;
    
    /**
     * 获取单例实例
     */
    static TimeoutManager& getInstance();
    
private:
    /**
     * 任务取消器 - 用于类型擦除
     */
    class TaskCanceller {
    public:
        explicit TaskCanceller(std::function<void()> cancelFunc) 
            : cancelFunc_(std::move(cancelFunc)) {}
        
        void cancel() { 
            if (cancelFunc_) cancelFunc_(); 
        }
        
    private:
        std::function<void()> cancelFunc_;
    };
    
    // 生成唯一任务ID
    uint64_t generateTaskId();
    
    // 清理完成的任务
    void cleanupTask(uint64_t taskId);
    
    // 组件
    std::unique_ptr<ThreadPool> threadPool_;    // 线程池
    std::unique_ptr<TimerWheel> timerWheel_;    // 时间轮
    
    // 任务管理
    std::atomic<uint64_t> nextTaskId_;          // 下一个任务ID
    mutable std::mutex tasksMutex_;             // 保护活跃任务映射
    std::unordered_map<uint64_t, std::shared_ptr<TaskCanceller>> activeTasks_; // 活跃任务
    
    // 统计信息
    mutable std::atomic<size_t> totalTasks_{0};
    mutable std::atomic<size_t> completedTasks_{0};
    mutable std::atomic<size_t> timeoutTasks_{0};
    mutable std::atomic<size_t> cancelledTasks_{0};
};

} // namespace timeout_manager